<!doctype html>
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>2.3 - FreeMarker 手册</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="FreeMarker 手册">
<meta property="og:title" content="2.3">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://freemarker.org/docs/versions_2_3.html">
<link rel="canoical" href="http://freemarker.org/docs/versions_2_3.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css">
</head>
<body itemscope itemtype="https://schema.org/Code">
    <meta itemprop="url" content="http://freemarker.org/docs/">
    <meta itemprop="name" content="FreeMarker 手册">

  <!--[if lte IE 9]>
  <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
  <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner">            <img itemprop="image" src="logo.png" alt="FreeMarker">
</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="http://freemarker.org/docs/api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://sourceforge.net/p/freemarker/bugs/new/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="toc.html" class="navigation-header">Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="toc.html"><span itemprop="name">FreeMarker 手册</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app.html"><span itemprop="name">附录</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">版本历史</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_3.html"><span itemprop="name">2.3</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div>    <div class="main-content site-width">
      <div class="content-wrapper">
  <div id="table-of-contents-wrapper" class="col-left">
      <script>var breadcrumb = ["FreeMarker 手册","附录","版本历史","2.3"];</script>
      <script src="toc.js"></script>
      <script src="docgen-resources/main.min.js"></script>
  </div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_3_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_2_8.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3" itemprop="headline">2.3</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_200" data-menu-target="autoid_200">Non backward-compatible changes!</a></li><li><a class="page-menu-link" href="#autoid_201" data-menu-target="autoid_201">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_202" data-menu-target="autoid_202">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_203" data-menu-target="autoid_203">Other changes</a></li><li><a class="page-menu-link" href="#autoid_204" data-menu-target="autoid_204">The history of the releases before the final version</a><ul><li><a class="page-menu-link" href="#autoid_205" data-menu-target="autoid_205">Differences between the final release and Release Candidate
4</a></li><li><a class="page-menu-link" href="#autoid_206" data-menu-target="autoid_206">Differences between the Release Candidate 4 and Release
Candidate 3</a></li><li><a class="page-menu-link" href="#autoid_207" data-menu-target="autoid_207">Differences between the Release Candidate 3 and Release
Candidate 2</a></li><li><a class="page-menu-link" href="#autoid_208" data-menu-target="autoid_208">Differences between the Release Candidate 2 and Release
Candidate 1</a></li><li><a class="page-menu-link" href="#autoid_209" data-menu-target="autoid_209">Differences between the Release Candidate 1 and Preview 16
releases</a></li><li><a class="page-menu-link" href="#autoid_210" data-menu-target="autoid_210">Differences between the Preview 16 and Preview 15
releases</a></li><li><a class="page-menu-link" href="#autoid_211" data-menu-target="autoid_211">Differences between the Preview 15 and Preview 14
releases</a></li><li><a class="page-menu-link" href="#autoid_212" data-menu-target="autoid_212">Differences between the Preview 14 and Preview 13
releases</a></li><li><a class="page-menu-link" href="#autoid_213" data-menu-target="autoid_213">Differences between the Preview 13 and Preview 12
releases</a></li><li><a class="page-menu-link" href="#autoid_214" data-menu-target="autoid_214">Differences between the Preview 12 and Preview 11
releases</a></li><li><a class="page-menu-link" href="#autoid_215" data-menu-target="autoid_215">Differences between the Preview 11 and Preview 10
releases</a></li><li><a class="page-menu-link" href="#autoid_216" data-menu-target="autoid_216">Differences between the Preview 10 and Preview 9
releases</a></li><li><a class="page-menu-link" href="#autoid_217" data-menu-target="autoid_217">Differences between the Preview 9 and Preview 8
releases</a></li><li><a class="page-menu-link" href="#autoid_218" data-menu-target="autoid_218">Differences between the Preview 8 and Preview 7
releases</a></li><li><a class="page-menu-link" href="#autoid_219" data-menu-target="autoid_219">Differences between the Preview 7 and Preview 6
releases</a></li><li><a class="page-menu-link" href="#autoid_220" data-menu-target="autoid_220">Differences between the Preview 6 and Preview 5
releases</a></li><li><a class="page-menu-link" href="#autoid_221" data-menu-target="autoid_221">Differences between the Preview 5 and Preview 4
releases</a></li><li><a class="page-menu-link" href="#autoid_222" data-menu-target="autoid_222">Differences between the Preview 4 and Preview 3
releases</a></li><li><a class="page-menu-link" href="#autoid_223" data-menu-target="autoid_223">Differences between the Preview 3 and Preview 2
releases</a></li><li><a class="page-menu-link" href="#autoid_224" data-menu-target="autoid_224">Differences between the Preview 2 and Preview 1
releases</a></li></ul></li></ul> </div><p>Date of release: 2004-June-15</p><p>FreeMarker 2.3 introduces numerous little new features and
        quality improvements compared to the 2.2.x series. The most notable
        improvements are the ability to define functions (methods) in
        templates, the ability to interpolate variables in string literals,
        the support for a variable number of macro parameters, and the more
        intelligent default object wrapper. Although none of the improvements
        is a drastic change, the 2.3.x series is not backward compatible with
        the 2.2.x series (see the list below), so you may choose to use it for
        new projects only.</p><p>Probably the most ``loudly promoted&#39;&#39; new feature is the totally
        redesigned XML wrapper. With the new XML wrapper FreeMarker targets a
        new application domain, which is similar to the application domain of
        XSLT: transforming complex XML to whatever textual output. Although
        this subproject is young, it is definitely usable in practice. See the
        <a href="xgui.html">XML Processing Guide</a> for more
        details.</p>
          



<h2 class="content-header header-section2" id="autoid_200">Non backward-compatible changes!</h2>


          <ul>
            <li>
              <p>Since interpolations (<code class="inline-code">${...}</code> and
              <code class="inline-code">#{...}</code>) now work inside string literals, the
              character sequence <code class="inline-code">${</code> and
              <code class="inline-code">#{</code> in string literals are reserved for that.
              So if you have something like <code class="inline-code">&lt;#set x =
              &quot;${foo}&quot;&gt;</code>, then you have to replace it with
              <code class="inline-code">&lt;#set x = r&quot;${foo}&quot;&gt;</code> -- beware, escapes
              such as <code class="inline-code">\n</code> will not work in raw
              (<code class="inline-code">r</code>) strings.</p>
            </li>

            <li>
              <p>The default (initial) value of the
              <code class="inline-code">strict_syntax</code> setting has been changed from
              <code class="inline-code">false</code> to <code class="inline-code">true</code>. When
              <code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
              tags with old syntax as <code class="inline-code">&lt;include
              &quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
              they go to the output as-is, like HTML tags do), and not as FTL
              tags. Such tags have to be rewritten to <code class="inline-code">&lt;#include
              &quot;foo.ftl&quot;&gt;</code>, since only parts that starts with
              <code class="inline-code">&lt;#</code>, <code class="inline-code">&lt;/#</code>,
              <code class="inline-code">&lt;@</code>, or <code class="inline-code">&lt;/@</code> count as
              FTL tags. Or, to recover the old transitional behavior, where
              both legacy and new tag syntax was recognized, you have to
              explicitly set <code class="inline-code">strict_syntax</code> to
              <code class="inline-code">false</code>:
              <code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
              individual templates you can force the old behavior by starting
              the template with <code class="inline-code">&lt;#ftl
              strict_syntax=false&gt;</code>. (For more information about
              why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
            </li>

            <li>
              <p>Several classes were moved from the
              <code class="inline-code">freemarker.template</code> package, to the new
              <code class="inline-code">freemarker.core</code> package:</p>

              <ul>
                <li>
                  &quot;Normal&quot; classes: <code class="inline-code">ArithmeticEngine</code>,
                  <code class="inline-code">Configurable</code>,
                  <em><code class="inline-code">Environment</code></em>
                </li>

                <li>
                  Exceptions:
                  <code class="inline-code">InvalidReferenceException</code>,
                  <code class="inline-code">NonBooleanException</code>,
                  <code class="inline-code">NonNumericalException</code>,
                  <code class="inline-code">NonStringException</code>,
                  <code class="inline-code">ParseException</code>,
                  <code class="inline-code">StopException</code>
                </li>

                <li>
                  Errors: <code class="inline-code">TokenMgrError</code>
                </li>
              </ul>

              <p>The main reason of the splitting of
              <code class="inline-code">freemarker.template</code> package was that the
              amount of &quot;expert&quot; public classes and interfaces grows too much,
              as we introduce API-s for third-party tools, such as debugging
              API.</p>
            </li>

            <li>
              <p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
              now returns <code class="inline-code">Object</code> instead of
              <code class="inline-code">TemplateModel</code>.</p>
            </li>

            <li>
              <p>White-space stripping is now more aggressive as before: it
              always removes leading and trailing white-space if the line only
              contains FTL tags. (Earlier the white-space was not removed if
              the tag was <code class="inline-code">&lt;#include
              <em class="code-color">...</em>&gt;</code> or user-defined
              directive tag with empty directive syntax as
              <code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
              <code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
              <code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now white-space
              is removed in these cases as well.) Also, white-space sandwiched
              between two non-outputting elements, such as macro definitions,
              assignments, imports, or property settings, is now ignored. More
              information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">模板开发指南/其它/空白处理/剥离空白</a></p>
            </li>

            <li>
              <p>The <code class="inline-code">function</code> directive is now used for
              defining methods. You should replace <code class="inline-code">function</code>
              with <code class="inline-code">macro</code> in your old templates. Note,
              however, that old <code class="inline-code">function</code>-s will still work
              if you don&#39;t use the <code class="inline-code">return</code> directive in
              them, and you invoke them with the deprecated the
              <code class="inline-code">call</code> directive.</p>
            </li>

            <li>
              <p>The expressions <code class="inline-code">as</code>,
              <code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
              keywords in the template language and cannot be used as
              top-level variable names without square-bracket syntax. If, by
              some chance, you have top-level variables that use one of these
              names, you will have to rename them, or use the square-bracket
              syntax with the <code class="inline-code">.vars</code> special variable:
              <code class="inline-code">.vars[&quot;in&quot;]</code>.</p>
            </li>

            <li>
              <p>The <code class="inline-code">?new</code> built-in, as it was
              implemented, was a security hole. Now, it only allows you to
              instantiate a java object that implements the
              <code class="inline-code">freemarker.template.TemplateModel</code> interface.
              If you want the functionality of the <code class="inline-code">?new</code>
              built-in as it existed in prior versions, make available an
              instance of the
              <code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
              class to your template. (For example:
              <code class="inline-code">myDataModel.put(&quot;objConstructor&quot;, new
              ObjectConstructor());</code>, and then in the template you
              can do this: <code class="inline-code">&lt;#assign aList =
              objConstructor(&quot;java.util.ArrayList&quot;, 100)&gt;</code>)</p>
            </li>

            <li>
              <p>Changes to the
              <code class="inline-code">FreemarkerServlet</code>:</p>

              <ul>
                <li>
                  <p>The <code class="inline-code">FreemarkerServlet</code> uses
                  <code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> by default
                  instead of <code class="inline-code">ObjectWrapper.BEANS_WRAPPER</code>.
                  What this means is that, by default, objects of type
                  <code class="inline-code">java.lang.String</code>,
                  <code class="inline-code">java.lang.Number</code>,
                  <code class="inline-code">java.util.List</code>, and
                  <code class="inline-code">java.util.Map</code> will be wrapped as
                  <code class="inline-code">TemplateModels</code> via the classes
                  <code class="inline-code">SimpleScalar</code>,
                  <code class="inline-code">SimpleNumber</code>,
                  <code class="inline-code">SimpleSequence</code>, and
                  <code class="inline-code">SimpleHash</code> respectively. Thus, the java
                  methods on those objects will not be available. The default
                  wrapper implementation in FreeMarker 2.3 automatically knows
                  how to wrap Jython objects, and also wraps
                  <code class="inline-code">org.w3c.dom.Node</code> objects into instances
                  of <code class="inline-code">freemarker.ext.dom.NodeModel</code>.</p>
                </li>

                <li>
                  <p>The <code class="inline-code">FreemarkerServlet</code> base
                  implementation no longer deduces the locale used for
                  templates with <code class="inline-code">HttpRequest.getLocale()</code>.
                  Rather, it simply delegates to the new protected method,
                  <code class="inline-code">deduceLocale</code>. The default implementation
                  of this method simply returns the value of configuration the
                  <code class="inline-code">locale</code> setting.</p>
                </li>
              </ul>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_201">Changes on the FTL side</h2>


          <ul>
            <li>
              <p>Interpolation in string literals. For convenience,
              interpolations are now supported in string literals. For
              example: <code class="inline-code">&lt;@message &quot;Hello ${user}!&quot; /&gt;</code>
              is the same as <code class="inline-code">&lt;@message &quot;Hello &quot; + user + &quot;!&quot;
              /&gt;</code></p>
            </li>

            <li>
              <p>Raw string literals: In string literals prefixed with
              <code class="inline-code">r</code>, interpolations and escape sequences will
              not be interpreted as special tokens. For example:
              <code class="inline-code">r&quot;\n${x}&quot;</code> will be simply interpreted as the
              character sequence <code class="inline-code">&#39;\&#39;</code>,
              <code class="inline-code">&#39;n&#39;</code>, <code class="inline-code">&#39;$&#39;</code>,
              <code class="inline-code">&#39;{&#39;</code>, <code class="inline-code">&#39;x&#39;</code>,
              <code class="inline-code">&#39;}&#39;</code>, and not as line-feed and the value of
              the <code class="inline-code">x</code> variable.</p>
            </li>

            <li>
              <p>Method variables can be defined in FTL, with the <a href="ref_directive_function.html#ref.directive.function"><code>function</code></a>
              directive.</p>
            </li>

            <li>
              <p>Support for a variable number of macro parameters. If the
              last parameter in a macro declaration ends with
              <code class="inline-code">...</code>, all extra parameters passed to the macro
              will be available via that parameter. For macros called with
              positional parameters, the parameter will be a sequence. For
              named parameters, the parameter will be a hash. Note that it all
              works with the new <code class="inline-code">function</code> directive as
              well.</p>
            </li>

            <li>
              <p>A new header parameter, <code class="inline-code">strip_text</code>,
              that removes all top-level text from a template. This is useful
              for ``include files&#39;&#39; to suppress newlines that separate the
              macro definitions. See <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code>
              directive</a></p>
            </li>

            <li>
              <p>New <a href="ref_specvar.html">special variable</a>:
              <code class="inline-code">.vars</code>. This is useful to read top-level
              variables with square bracket syntax, for example
              <code class="inline-code">.vars[&quot;name-with-hyphens&quot;]</code> and
              <code class="inline-code">.vars[dynamicName]</code>.</p>
            </li>

            <li>
              <p><code class="inline-code">macro</code> and assignment directives now
              accept arbitrary destination variable name with quoted syntax.
              For example: <code class="inline-code">&lt;#macro
              &quot;name-with-hyphens&quot;&gt;<em class="code-color">...</em></code>
              or <code class="inline-code">&lt;#assign &quot;foo bar&quot; = 123&gt;</code>.</p>
            </li>

            <li>
              <p>The <code class="inline-code">?keys</code> and
              <code class="inline-code">?values</code> hash built-ins now return sequences.
              In practical terms this means you can access their sizes or
              retrieve their sub variables by index, and use all of the <a href="ref_builtins_sequence.html">sequence built-ins</a>. (Note
              for the programmers: The <code class="inline-code">TemplateHashModelEx</code>
              interface has not been changed. Your old code will work. See the
              API documentation to see why.)</p>
            </li>

            <li>
              <p>Existence built-ins (<code class="inline-code">?default</code>,
              <code class="inline-code">?exists</code>, etc.) are now working with sequence
              sub variables as well. Read the documentation of the
              <code class="inline-code">default</code> built-in for more information.</p>
            </li>

            <li>
              <p>White-space stripping is now more aggressive as before: it
              always removes leading and trailing white-space if the line only
              contains FTL tags. (Earlier the white-space was not removed if
              the tag was <code class="inline-code">&lt;#include
              <em class="code-color">...</em>&gt;</code> or user-defined
              directive tag with empty directive syntax as
              <code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
              <code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
              <code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now white-space
              is removed in these cases as well.) Also, top-level white-space
              that separates macro definitions and/or assignments is now
              ignored. More information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">模板开发指南/其它/空白处理/剥离空白</a></p>
            </li>

            <li>
              <p>White-space stripping can be disabled for a single line
              with the <a href="ref_directive_nt.html#ref.directive.nt"><code>nt</code></a>
              directive (for No Trim).</p>
            </li>

            <li>
              <p>Hashes can be concatenated using the <code class="inline-code">+</code>
              operator. The keys in the hash on the right-hand side take
              precedence.</p>
            </li>

            <li>
              <p>New built-ins for Java and JavaScript string escaping:
              <a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
            </li>

            <li>
              <p>The <code class="inline-code">replace</code> and
              <code class="inline-code">split</code> built-ins now support case-insensitive
              comparsion and regular expressions (J2SE 1.4+ only), and some
              other new options. More information can be found <a href="ref_builtins_string.html#ref_builtin_string_flags">here</a>.</p>
            </li>

            <li>
              <p>New built-in for regular expression matching (J2SE 1.4+
              only): <a href="ref_builtins_string.html#ref_builtin_matches"><code>matches</code></a></p>
            </li>

            <li>
              <p>New built-in, <code class="inline-code">eval</code>, to evaluate a
              string as FTL expression. For example
              <code class="inline-code">&quot;1+2&quot;?eval</code> returns the number 3.</p>
            </li>

            <li>
              <p>New built-ins for Java and JavaScript string escaping:
              <a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
            </li>

            <li>
              <p>New special variables to read the value of the locale
              setting: <code class="inline-code">locale</code>, <code class="inline-code">lang</code>. See
              more <a href="ref_specvar.html">in the
              reference...</a></p>
            </li>

            <li>
              <p>New special variable to read the FreeMarker version
              number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
            </li>

            <li>
              <p>Tree new directives, <code class="inline-code">recurse</code>,
              <code class="inline-code">visit</code> and <code class="inline-code">fallback</code>, were
              introduced to support declarative node-tree processing. These
              are meant to be used typically (though not exclusively) for
              processing XML input. Together with this, a new variable type
              has been introduced, the node type. See the <a href="xgui_declarative.html">chapter on declarative XML
              processing</a> for more details.</p>
            </li>

            <li>
              <p>The <code class="inline-code">?new</code> built-in, as it was
              implemented, was a security hole. Now, it only allows you to
              instantiate a java object that implements the
              <code class="inline-code">freemarker.template.TemplateModel</code> interface.
              <span class="marked-for-programmers">If you want the functionality of
              the <code class="inline-code">?new</code> built-in as it existed in prior
              versions, make available an instance of the
              <code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
              class to your template. (For example:
              <code class="inline-code">myDataModel.put(&quot;objConstructor&quot;, new
              ObjectConstructor());</code>, and then in the template you
              can do this: <code class="inline-code">&lt;#assign aList =
              objConstructor(&quot;java.util.ArrayList&quot;,
              100)&gt;</code>)</span></p>
            </li>

            <li>
              <p>Variable names can contain <code class="inline-code">@</code> anywhere
              (without using quote-bracket syntax). For example:
              <code class="inline-code">&lt;#assign x@@@ = 123&gt;</code> is valid.</p>
            </li>

            <li>
              <p>The expressions <code class="inline-code">as</code>,
              <code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
              keywords in the template language and cannot be used as
              top-level variable names without square-bracket syntax (as
              <code class="inline-code">.vars[&quot;in&quot;]</code>).</p>
            </li>

            <li>
              <p>New parameter to the <a href="ref_directive_ftl.html"><code>ftl</code>
              directive</a>: <code class="inline-code">attributes</code>. The value of
              this attribute is a hash that associates arbitrary attributes
              (name-value pairs) to the template. The values of the attributes
              can be of any type (string, number, sequence... etc.).
              FreeMarker doesn&#39;t try to understand the meaning of the
              attributes. It&#39;s up to the application that encapsulates
              FreeMarker (as a Web application framework). Thus, the set of
              allowed attributes and their semantic is application (Web
              application framework) dependent.</p>
            </li>

            <li>
              <p>Other minor quality improvements...</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_202">Changes on the Java side</h2>


          <ul>
            <li>
              <p>Smarter default object wrapping: The default object
              wrapper is now
              <code class="inline-code">freemarker.template.DefaultObjectWrapper</code>,
              which falls back on wrapping arbitrary objects as beans using
              the <code class="inline-code">freemarker.ext.beans.BeansWrapper</code>. Also,
              it will wrap <code class="inline-code">org.w3c.dom.Node</code> objects with
              the new DOM wrapper. Also, it is aware of Jython objects, and
              will use <code class="inline-code">freemarker.ext.jython.JythonWrapper</code>
              if the object passed in is a Jython object. (We count it as a
              backward compatible change, since this new object wrapper wraps
              differently only those objects that the old wrapper was not able
              to wrap, so it has thrown exception.)</p>
            </li>

            <li>
              <p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
              now returns <code class="inline-code">Object</code> instead of
              <code class="inline-code">TemplateModel</code>.</p>
            </li>

            <li>
              <p>The default (initial) value of the
              <code class="inline-code">strict_syntax</code> setting has been changed from
              <code class="inline-code">false</code> to <code class="inline-code">true</code>. When
              <code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
              tags with old syntax as <code class="inline-code">&lt;include
              &quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
              they go to the output as-is, like HTML tags do), and not as FTL
              tags. Such tags have to be rewritten to <code class="inline-code">&lt;#include
              &quot;foo.ftl&quot;&gt;</code>, since only parts that starts with
              <code class="inline-code">&lt;#</code>, <code class="inline-code">&lt;/#</code>,
              <code class="inline-code">&lt;@</code>, or <code class="inline-code">&lt;/@</code> count as
              FTL tags. Or, to recover the old transitional behavior, where
              both legacy and new tag syntax was recognized, you have to
              explicitly set <code class="inline-code">strict_syntax</code> to
              <code class="inline-code">false</code>:
              <code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
              individual templates you can force the old behavior by starting
              the template with <code class="inline-code">&lt;#ftl
              strict_syntax=false&gt;</code>. (For more information about
              why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
            </li>

            <li>
              <p>New <code class="inline-code">CacheStorage</code> implementation:
              <code class="inline-code">freemarker.cache.MruCacheStorage</code>. This cache
              storage implements a two-level Most Recently Used cache. In the
              first level, items are strongly referenced up to the specified
              maximum. When the maximum is exceeded, the least recently used
              item is moved into the second level cache, where they are softly
              referenced, up to another specified maximum.
              <code class="inline-code">freemarker.cache.SoftCachseStorage</code> and
              <code class="inline-code">StrongCachseStorage</code> are deprected,
              <code class="inline-code">MruCachseStorage</code> is used everywhere instead.
              The default cache storage is now an
              <code class="inline-code">MruCachseStorage</code> object with 0 strong size,
              and infinite soft size.
              <code class="inline-code">Configuration.setSetting</code> for
              <code class="inline-code">cache_storage</code> now understands string values
              as <code class="inline-code">&quot;strong:200, soft:2000&quot;</code>.</p>
            </li>

            <li>
              <p>For <code class="inline-code">BeansWrapper</code> generated models, you
              can now use the <code class="inline-code">${obj.method(args)}</code> syntax to
              invoke methods whose return type is <code class="inline-code">void</code>.
              <code class="inline-code">void</code> methods now return
              <code class="inline-code">TemplateModel.NOTHING</code> as their return
              value.</p>
            </li>

            <li>
              <p><code class="inline-code">freemarker.template.SimpleHash</code> now can
              wrap read-only <code class="inline-code">Map</code>-s, such as the map of HTTP
              request parameters in Servlet API.</p>
            </li>

            <li>
              <p>The <code class="inline-code">TemplateNodeModel</code> interface was
              introduced to support recursive processing of trees of nodes.
              Typically, this will be used in relation to XML.</p>
            </li>

            <li>
              <p>New package: <code class="inline-code">freemarker.ext.dom</code>. This
              contains the new XML wrapper, that supports the processing of
              XML documents using the visitor pattern (i.e. with
              <code class="inline-code">&lt;#visit <em class="code-color">...</em>&gt;</code>
              and similar directives), and to provide more convenient XML
              traversing as the legacy wrapper. See the <a href="xgui.html">XML processing guide</a> for more
              details.</p>
            </li>

            <li>
              <p>New package: <code class="inline-code">freemarker.core</code>. Classes
              used by mostly power-users was moved here from the
              <code class="inline-code">freemarker.template</code> package. The main reason
              of the splitting of <code class="inline-code">freemarker.template</code>
              package was that the amount of &quot;expert&quot; public classes and
              interfaces grows too much, as we introduce API-s for third-party
              tools, such as debugging API.</p>
            </li>

            <li>
              <p>New package: <code class="inline-code">freemarker.debug</code>. This
              provides a debugging API, by which you can debug executing
              templates through network (RMI). You have to write the front-end
              (client), as the API is just the server side. For more
              information please read the JavaDoc of the
              <code class="inline-code">freemarker.debug</code> package.</p>
            </li>

            <li>
              <p>You can query the FreeMarker version number with static
              method <code class="inline-code">Configuration.getVersionNumber()</code>.
              Also, the <code class="inline-code">Manifest.mf</code> included in
              <code class="inline-code">freemarker.jar</code> now contains the FreeMarker
              version number, furthermore, executing it with <code class="inline-code">java
              -jar freemarker.jar</code> will print the version number to
              the stdout.</p>
            </li>

            <li>
              <p>Added a new protected <code class="inline-code">FreemarkerServlet</code>
              method: <code class="inline-code">Configuration
              getConfiguration()</code>.</p>
            </li>

            <li>
              <p>Date support is now labeled as final. (It was experimental
              earlier.)</p>
            </li>

            <li>
              <p>The <code class="inline-code">BeansWrapper</code> has been improved to
              prevent some security exceptions when introspecting.</p>
            </li>

            <li>
              <p>Other minor quality improvements and extensions...</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_203">Other changes</h2>


          <ul>
            <li>
              <p>Fixes and improvements in the Manual and in the API
              JavaDoc.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_204">The history of the releases before the final version</h2>


          
            



<h3 class="content-header header-section3" id="autoid_205">Differences between the final release and Release Candidate
            4</h3>


            <ul>
              <li>
                <p>Added a new special variable to print the FreeMarker
                version number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
              </li>

              <li>
                <p>Minor documentation fixes and improvements.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_206">Differences between the Release Candidate 4 and Release
            Candidate 3</h3>


            <ul>
              <li>
                <p>The <code class="inline-code">BeansWrapper</code> has been improved to
                prevent some security exceptions when introspecting.</p>
              </li>

              <li>
                <p>The <code class="inline-code">FreemarkerXmlTask</code> has two new
                sub-tasks that can be used to prepare template execution with
                Jython scripts: <code class="inline-code">prepareModel</code> and
                <code class="inline-code">prepareEnvironment</code>. The
                <code class="inline-code">jython</code> sub-task is now deprecated, and does
                the same as <code class="inline-code">prepareEnvironment</code>. See the
                Java API documentation for more details.</p>
              </li>

              <li>
                <p>New special variable to read the FreeMarker version
                number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
              </li>

              <li>
                <p>Bugfix: Greater-than sign doesn&#39;t confuse the
                <code class="inline-code">eval</code> built-in anymore.</p>
              </li>

              <li>
                <p>Bugfix: The <code class="inline-code">BeansWrapper</code> now wrapps
                the <code class="inline-code">null</code> return values of methods
                appropriately.</p>
              </li>

              <li>
                <p>Bugfix: The <code class="inline-code">FreemarkerXmlTask</code> doesn&#39;t
                need Jython classes anymore, unless you really use Jython
                scripts. Several other bugfixes in the Jython related
                features.</p>
              </li>

              <li>
                <p>Bugfix: If the template exception handler has ignored
                the exception, errors occurring in interpolations inside FTL
                tags (e.g. <code class="inline-code">&lt;#if &quot;foo${badVar}&quot; !=
                &quot;foobar&quot;&gt;</code>) were handled in the same way as errors
                occuring in interpolations outside FTL tags. Thus, the
                directive call was not skipped, and the problematic
                interpolation was replaced with an empty string. (This was
                inconsistent with the behavior of <code class="inline-code">&lt;#if
                &quot;foo&quot;+badVar != &quot;foobar&quot;&gt;</code>, which should be 100%
                equivalent with the previous example.)</p>
              </li>

              <li>
                <p>Bugfix: The <code class="inline-code">FileTemplateLoader</code> is now
                more robust when it receives paths that are malformed
                according the native file system. In the earlier version such
                paths sometimes caused unexpected
                <code class="inline-code">IOException</code> that aborted the searching for
                the template in further
                <code class="inline-code">FileTemplateLoader</code>-s when you use the
                <code class="inline-code">MultiTemplateLoader</code>.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_207">Differences between the Release Candidate 3 and Release
            Candidate 2</h3>


            <ul>
              <li>
                <p>Bugfix: Fixing a fatal bug in the template cache that
                was introduced with the latest cache ``bugfix&#39;&#39;. The template
                cache has always reloaded the unchanged template when the
                update delay has been elapsed, until the template has been
                actually changed, in which case it has never reloaded the
                template anymore.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_208">Differences between the Release Candidate 2 and Release
            Candidate 1</h3>


            <ul>
              <li>
                <p>Bugfix: The template cache didn&#39;t reload the template
                when it was replaced with an older version.</p>
              </li>

              <li>
                <p>API JavaDoc fix: date/time related classes/interfaces
                were marked as experimental. They are not experimental.</p>
              </li>

              <li>
                <p>Minor site improvements.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_209">Differences between the Release Candidate 1 and Preview 16
            releases</h3>


            <ul>
              <li>
                <p><em>Warning! Non-backward-compatible
                change!</em> The default (initial) value of the
                <code class="inline-code">strict_syntax</code> setting has been changed from
                <code class="inline-code">false</code> to <code class="inline-code">true</code>. When
                <code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
                tags with old syntax as <code class="inline-code">&lt;include
                &quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
                they go to the output as-is, like HTML tags do), and not as
                FTL tags. Such tags have to be rewritten to
                <code class="inline-code">&lt;#include &quot;foo.ftl&quot;&gt;</code>, since only
                parts that starts with <code class="inline-code">&lt;#</code>,
                <code class="inline-code">&lt;/#</code>, <code class="inline-code">&lt;@</code>, or
                <code class="inline-code">&lt;/@</code> count as FTL tags. Or, to recover
                the old transitional behavior, where both legacy and new tag
                syntax was recognized, you have to explicitly set
                <code class="inline-code">strict_syntax</code> to <code class="inline-code">false</code>:
                <code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
                individual templates you can force the old behavior by
                starting the template with <code class="inline-code">&lt;#ftl
                strict_syntax=false&gt;</code>. (For more information about
                why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
              </li>

              <li>
                <p>New parameter to the <a href="ref_directive_ftl.html"><code>ftl</code>
                directive</a>: <code class="inline-code">attributes</code>. The value of
                this attribute is a hash that associates arbitrary attributes
                (name-value pairs) to the template. The values of the
                attributes can be of any type (string, number, sequence...
                etc.). FreeMarker doesn&#39;t try to understand the meaning of the
                attributes. It&#39;s up to the application that encapsulates
                FreeMarker (as a Web application framework). Thus, the set of
                allowed attributes and their semantic is application (Web
                application framework) dependent.</p>
              </li>

              <li>
                <p>Bugfix:
                <code class="inline-code">freemarker.template.utility.DeepUnwrap</code>
                unwrapped sequences to empty
                <code class="inline-code">ArrayList</code>-s.</p>
              </li>

              <li>
                <p>Bugfix: If you included/imported a template with
                <code class="inline-code">*/</code> in path (acquisition), and that template
                in turn itself included/imported another template with
                <code class="inline-code">*/</code> in path, it may failed.</p>
              </li>

              <li>
                <p>New methods to the
                <code class="inline-code">freemarker.core.Environment</code>:
                <code class="inline-code">importLib(Template loadedTemplate, java.lang.String
                namespace)</code>,
                <code class="inline-code">getTemplateForImporting(...)</code>,
                <code class="inline-code">getTemplateForInclusion(...)</code>.</p>
              </li>

              <li>
                <p>Improvements in the
                <code class="inline-code">java.io.IOException</code> related error messages
                of the <code class="inline-code">include</code> and
                <code class="inline-code">import</code> directives.</p>
              </li>

              <li>
                <p>Minor improvements in the documentation.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_210">Differences between the Preview 16 and Preview 15
            releases</h3>


            <ul>
              <li>
                <p>New package: <code class="inline-code">freemarker.debug</code>. This
                provides a debugging API, by which you can debug executing
                templates through network (RMI). You have to write the
                front-end (client), as the API is just the server side. For
                more information please read the JavaDoc of the
                <code class="inline-code">freemarker.debug</code> package. (The debugging
                API is present for a while, just I forgot to announce it in
                the version history. Sorry for that.)</p>
              </li>

              <li>
                <p>Bugfix: With the new XML wrapper,
                <code class="inline-code">@@markup</code> and similar special keys:</p>

                <ul>
                  <li>
                    <p>have returned
                    <code class="inline-code">&lt;foo&gt;&lt;/foo&gt;</code> for empty
                    elements instead of <code class="inline-code">&lt;foo /&gt;</code>.
                    Other than it was needlessly verbose, it has confused
                    browsers if you generate HTML.</p>
                  </li>

                  <li>
                    <p>have showed the attributes that have no explicitly
                    given value in the original document, just a default value
                    coming form the DTD.</p>
                  </li>

                  <li>
                    <p>have forgot to put space before the system
                    identifier in the <code class="inline-code">&lt;!DOCTYPE
                    <em class="code-color">...</em>&gt;</code>.</p>
                  </li>
                </ul>
              </li>

              <li>
                <p>Bugfix: XPath with Jaxen has died with
                <code class="inline-code">NullPointerException</code> if the context was an
                empty node set.</p>
              </li>

              <li>
                <p>A bit more intelligent Xalan XPath error
                messages.</p>
              </li>

              <li>
                <p>Revoked fallback-to-classloader logic from the template
                cache.</p>
              </li>

              <li>
                <p>From now, if no XPath engine is available, and the hash
                key in an ``XML query&#39;&#39; can&#39;t be interpreted without XPath, an
                error will tell this clearly, rather than silently returning
                undefined variable (null).</p>
              </li>

              <li>
                <p>Bugfix: Some templates have caused the parser to
                die.</p>
              </li>

              <li>
                <p>Some other minor improvements here and there...</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_211">Differences between the Preview 15 and Preview 14
            releases</h3>


            <ul>
              <li>
                <p>Bugfix: The new default template cache storage
                (<code class="inline-code">MruCacheStorage</code>) has started to
                continually fail with <code class="inline-code">NullPointerException</code>
                from a random point of time, usually when the memory usage was
                high in the JVM.</p>
              </li>

              <li>
                <p>Bugfix: In error messages, when the quoted FTL directive
                had nested content, that was quoted as well, so the quotation
                could be very long and expose nested lines needlessly.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_212">Differences between the Preview 14 and Preview 13
            releases</h3>


            <ul>
              <li>
                <p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
                now returns <code class="inline-code">Object</code> instead of
                <code class="inline-code">TemplateModel</code>.</p>
              </li>

              <li>
                <p>Fixes and improvements for XPath with Jaxen (not Xalan).
                Non-node-set XPath expressions are now working. FreeMarker
                variables are accessible in XPath expressions with XPath
                variable references (e.g.
                <code class="inline-code">doc[&quot;book/chapter[title=$currentTitle]&quot;]</code>).</p>
              </li>

              <li>
                <p><code class="inline-code">freemarker.cache.SoftCachseStorage</code>
                and <code class="inline-code">StrongCachseStorage</code> is deprected. The
                more flexible <code class="inline-code">MruCachseStorage</code> is used
                instead everywhere. The default cache storage is now an
                <code class="inline-code">MruCachseStorage</code> object with 0 strong size,
                and infinite soft size.
                <code class="inline-code">Configuration.setSetting</code> for
                <code class="inline-code">cache_storage</code> now understands string values
                as <code class="inline-code">&quot;strong:200, soft:2000&quot;</code>.</p>
              </li>

              <li>
                <p>Bugfix:
                <code class="inline-code">freemarker.cache.MruCachseStorage</code> has died
                with <code class="inline-code">ClassCastException</code> sometimes.</p>
              </li>

              <li>
                <p>New built-ins for Java and JavaScript string escaping:
                <a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
              </li>

              <li>
                <p><code class="inline-code">freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLER</code>
                now prints more HTML-context-proof messages.</p>
              </li>

              <li>
                <p>You can query the FreeMarker version number with static
                method <code class="inline-code">Configuration.getVersionNumber()</code>.
                Also, the <code class="inline-code">Manifest.mf</code> included in
                <code class="inline-code">freemarker.jar</code> now contains the FreeMarker
                version number, furthermore, executing it with <code class="inline-code">java
                -jar freemarker.jar</code> will print the version number to
                the stdout.</p>
              </li>

              <li>
                <p>Added a new protected
                <code class="inline-code">FreemarkerServlet</code> method:
                <code class="inline-code">Configuration getConfiguration()</code>.</p>
              </li>

              <li>
                <p>Bugfix: FreeMarker has frozen on empty conditional
                blocks in certain contexts.</p>
              </li>

              <li>
                <p>Bugfix: Methods called twice on an object using the
                <code class="inline-code">list</code> directive, as
                <code class="inline-code">parent.getChildren()</code> with
                <code class="inline-code">&lt;#list parent.children as child&gt;
                ...&lt;/#list&gt;</code></p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_213">Differences between the Preview 13 and Preview 12
            releases</h3>


            <ul>
              <li>
                <p>White-space stripping is now more aggressive as before:
                it always removes leading and trailing white-space if the line
                only contains FTL tags. (Earlier the white-space was not
                removed if the tag was <code class="inline-code">&lt;#include
                <em class="code-color">...</em>&gt;</code> or user-defined
                directive tag with empty directive syntax as
                <code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
                <code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
                <code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now
                white-space is removed in these cases as well.) Also,
                top-level white-space that separates macro definitions and/or
                assignments is now ignored. More information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">模板开发指南/其它/空白处理/剥离空白</a></p>
              </li>

              <li>
                <p>White-space stripping can be disabled for a single line
                with the <a href="ref_directive_nt.html#ref.directive.nt"><code>nt</code></a>
                directive (for No Trim).</p>
              </li>

              <li>
                <p>A new directive for the declarative XML processing:
                <a href="ref_directive_visit.html#ref.directive.fallback"><code>fallback</code></a></p>
              </li>

              <li>
                <p><code class="inline-code">freemarker.template.SimpleHash</code> now
                can wrap read-only <code class="inline-code">Map</code>-s, such as the map
                of HTTP request parameters in Servlet API.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_214">Differences between the Preview 12 and Preview 11
            releases</h3>


            <p>The only change between this and the previous preview
            release is that Preview 11 had a bug where DOM trees would
            <em>never</em> be garbage-collected.</p>
          

          
            



<h3 class="content-header header-section3" id="autoid_215">Differences between the Preview 11 and Preview 10
            releases</h3>


            <ul>
              <li>
                <p>Many XML related changes. Some of them are incompatible
                with the previous preview releases! For a more detailed
                explanation of how XML related features now work, see: <a href="xgui.html">XML处理指南</a></p>

                <ul>
                  <li>
                    <p>Attention! Attribute queries such as
                    <code class="inline-code">foo.@bar</code> now return sequences
                    (similarly to child element queries and XPath queries),
                    not single nodes. Because of the rule with node sequences
                    of size 1, it is still good to write
                    <code class="inline-code">${foo.@bar}</code>, but built-ins such as
                    <code class="inline-code">?exists</code>, <code class="inline-code">?if_exists</code>
                    or <code class="inline-code">?default</code> don&#39;t work as before. For
                    example, instead of
                    <code class="inline-code">foo.@bar?default(&#39;black&#39;)</code>, you now have
                    to write <code class="inline-code">foo.@bar[0]?default(&#39;black&#39;)</code>.
                    So if you have used existence built-ins with attributes,
                    you have to find those occurrences in the templates and
                    add that <code class="inline-code">[0]</code>.</p>
                  </li>

                  <li>
                    <p>Attention! XML name-space handling has been totally
                    reworked and is absolutely incompatible with pre 10. Don&#39;t
                    worry about this if none of your XML input documents use
                    you use <code class="inline-code">xmlns</code> attributes. Worry,
                    though, if you have utilized the ``loose mode&#39;&#39;, where
                    only the local name of elements were compared, because
                    that&#39;s now gone. Sorry...</p>
                  </li>

                  <li>
                    <p>Attention! Special-keys <code class="inline-code">@@</code> and
                    <code class="inline-code">@*</code> now return a sequence of attribute
                    nodes instead of the hash of them.</p>
                  </li>

                  <li>
                    <p>Several hash keys are now working for node sequences
                    that store multiple nodes. For example, to get the list of
                    all <code class="inline-code">para</code> elements of all
                    <code class="inline-code">chapter</code>-s, just write
                    <code class="inline-code">doc.book.chapter.para</code>. Or, to get list
                    of title attributes of all <code class="inline-code">chapter</code>-s
                    write <code class="inline-code">doc.book.chapter.@title</code>.</p>
                  </li>

                  <li>
                    <p>New special hash keys: <code class="inline-code">**</code>,
                    <code class="inline-code">@@start_tag</code>,
                    <code class="inline-code">@@end_tag</code>,
                    <code class="inline-code">@@attribute_markup</code>,
                    <code class="inline-code">@@text</code>,
                    <code class="inline-code">@@qname</code>.</p>
                  </li>

                  <li>
                    <p><code class="inline-code">?parent</code> for attribute nodes now
                    returns the element node the attribute node belongs
                    to.</p>
                  </li>

                  <li>
                    <p>You can use Jaxen instead of Xalan for XPath
                    expressions, if you call the static
                    <code class="inline-code">freemarker.ext.dom.NodeModel.useJaxenXPathSupport()</code>
                    method once. We plan to use Jaxen automatically instead of
                    Xalan if it is available, just the Jaxen support is not
                    fully functional yet.</p>
                  </li>
                </ul>
              </li>

              <li>
                <p>New special variable: <code class="inline-code">.vars</code>. This is
                useful to read top-level variables with square bracket syntax,
                for example <code class="inline-code">.vars[&quot;name-with-hyphens&quot;]</code> and
                <code class="inline-code">.vars[dynamicName]</code>.</p>
              </li>

              <li>
                <p>New built-in, <code class="inline-code">eval</code>, to evaluate a
                string as FTL expression. For example
                <code class="inline-code">&quot;1+2&quot;?eval</code> returns the number 3.</p>
              </li>

              <li>
                <p><code class="inline-code">FreemarkerServlet</code> now uses the
                configuration&#39;s <code class="inline-code">locale</code> setting, rather than
                <code class="inline-code">Locale.getDefault()</code>, to set the locale of
                the templates. Also, the signature of the
                <code class="inline-code">deduceLocale</code> method has been
                changed.</p>
              </li>

              <li>
                <p>We have a new (beta status)
                <code class="inline-code">CacheStorage</code> implementation:
                <code class="inline-code">freemarker.cache.MruCacheStorage</code>. This
                cache storage implements a two-level Most Recently Used cache.
                In the first level, items are strongly referenced up to the
                specified maximum. When the maximum is exceeded, the least
                recently used item is moved into the second level cache, where
                they are softly referenced, up to another specified maximum.
                You can plug to try it with <code class="inline-code">cfg.setCacheStorage(new
                freemarker.cache.MruCacheStorage(maxStrongSize,
                maxSoftSize))</code>.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_216">Differences between the Preview 10 and Preview 9
            releases</h3>


            <ul>
              <li>
                <p>The special key <code class="inline-code">@@xmlns</code> was removed
                in favor of a new FTL directive for the same purpose,
                <code class="inline-code">&lt;#xmlns...&gt;</code>.</p>
              </li>

              <li>
                <p>By default, the system is stricter about the use of
                namespace prefixes. In general, you must use a prefix to
                qualify subelements that are associated with an XML
                nampespace. You can do this with the new
                <code class="inline-code">&lt;#xmlns...&gt;</code> directive, but prefixes
                declared in the input XML doc will actually work with no
                declaration.</p>
              </li>

              <li>
                <p>Introduced a new special key called
                <code class="inline-code">@@text</code> that returns all the text nodes
                contained (recursively) in an element all concatenated
                together.</p>
              </li>

              <li>
                <p>Either Jaxen or Xalan can be used to provide XPath
                functionality. Prior versions only worked with Xalan.</p>
              </li>

              <li>
                <p>The <code class="inline-code">FreemarkerServlet</code> uses
                <code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> by default
                instead of <code class="inline-code">ObjectWrapper.BEANS_WRAPPER</code>.
                What this means is that, by default, objects of type
                <code class="inline-code">java.lang.String</code>,
                <code class="inline-code">java.lang.Number</code>,
                <code class="inline-code">java.util.List</code>, and
                <code class="inline-code">java.util.Map</code> will be wrapped as
                <code class="inline-code">TemplateModels</code> via the classes
                <code class="inline-code">SimpleScalar</code>,
                <code class="inline-code">SimpleNumber</code>,
                <code class="inline-code">SimpleSequence</code>, and
                <code class="inline-code">SimpleHash</code> respectively. Thus, the java
                methods on those objects will not be available. The default
                wrapper implementation in FreeMarker 2.3 automatically knows
                how to wrap Jython objects, and also wraps
                <code class="inline-code">org.w3c.dom.Node</code> objects into instances of
                <code class="inline-code">freemarker.ext.dom.NodeModel</code>.</p>
              </li>

              <li>
                <p>The <code class="inline-code">FreemarkerServlet</code> base
                implementation no longer deduces the locale to use from the
                HttpRequest.getLocale() hook. Rather, it simply delegates to a
                <code class="inline-code">deduceLocale()</code> hook that is overridable in
                subclasses. The base implementation simply uses
                <code class="inline-code">Locale.getDefault()</code></p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_217">Differences between the Preview 9 and Preview 8
            releases</h3>


            <ul>
              <li>
                <p>Fixed bugs introduced with Preview 8: XPath,
                <code class="inline-code">@@markup</code> and
                <code class="inline-code">@@nested_markup</code> now works with the document
                node.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_218">Differences between the Preview 8 and Preview 7
            releases</h3>


            <ul>
              <li>
                <p><code class="inline-code">macro</code> and assignment directives now
                accept arbitrary destination variable name with quoted syntax.
                For example: <code class="inline-code">&lt;#macro
                &quot;foo-bar&quot;&gt;<em class="code-color">...</em></code> or
                <code class="inline-code">&lt;#assign &quot;this+that&quot; = 123&gt;</code>. This is
                important, because XML element names can contain hyphen, and
                it was not possible to define a handler macro for those
                elements, till now.</p>
              </li>

              <li>
                <p>Special key <code class="inline-code">@@content</code> was renamed to
                <code class="inline-code">@@nested_markup</code>.</p>
              </li>

              <li>
                <p>Fixed outdated XML related Manual parts (that were
                outdated even in Preview 7).</p>
              </li>

              <li>
                <p>Better parse-error messages.</p>
              </li>

              <li>
                <p>Minor bugfixes here and there...</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_219">Differences between the Preview 7 and Preview 6
            releases</h3>


            <ul>
              <li>
                <p>Caching of XPath queries should lead to significant
                performance improvements for XML processing, at least when
                XPath is heavily used.</p>
              </li>

              <li>
                <p>Refinements in handling of XML namespaces in the XML
                processing functionality. The new
                <code class="inline-code">strict_namespace_handling</code> setting
                introduced in 2.3pre6 was removed. A general-purpose solution
                was arrived at that should make that configuration setting
                unnecessary.</p>
              </li>

              <li>
                <p>Special key <code class="inline-code">@xmlns</code> was renamed to
                @@xmlns. Reserved namespace prefix <code class="inline-code">default</code>
                was renamed to <code class="inline-code">@@default</code>.</p>
              </li>

              <li>
                <p>The <code class="inline-code">ftl</code> directive now accepts
                non-string types.</p>
              </li>

              <li>
                <p>New special keys were introduced for XML node wrappers
                in the freemarker.ext.dom package. The
                <code class="inline-code">@@markup</code> key returns the literal markup
                that make up that element and the <code class="inline-code">@@content</code>
                key returns all the element&#39;s markup excluding the opening and
                closing tags.</p>
              </li>

              <li>
                <p>Minor bugfixes here and there...</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_220">Differences between the Preview 6 and Preview 5
            releases</h3>


            <ul>
              <li>
                <p>Existence built-ins (<code class="inline-code">?default</code>,
                <code class="inline-code">?exists</code>, etc.) now work with sequence sub
                variables as well. Read the <a href="ref_directive_switch.html#ref.directive.default">documentation of the
                <code>default</code> built-in</a> for more
                information.</p>
              </li>

              <li>
                <p>The <code class="inline-code">matches</code> built-in now returns a
                sequence instead of a collection.</p>
              </li>

              <li>
                <p>Refinements in handling of XML namespaces in the XML
                processing functionality. A new setting,
                <code class="inline-code">strict_namespace_handling</code> was introduced.
                If this is set (it is off by default) any node-handling macro
                used in with the visit/recurse machinery must be from a macro
                library that declares in its ftl header that it handles the
                namespace in question.</p>
              </li>

              <li>
                <p>Minor bugfixes here and there...</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_221">Differences between the Preview 5 and Preview 4
            releases</h3>


            <ul>
              <li>
                <p>The <code class="inline-code">replace</code> and
                <code class="inline-code">split</code> built-ins now support
                case-insensitive comparison and regular expressions (J2SE 1.4+
                only), and some other new options. More information can be
                found <a href="ref_builtins_string.html#ref_builtin_string_flags">here</a>.</p>
              </li>

              <li>
                <p>New butilt-in for regular expression matching (J2SE 1.4+
                only): <a href="ref_builtins_string.html#ref_builtin_matches"><code>matches</code></a></p>
              </li>

              <li>
                <p>Minor bugfixes here and there...</p>
              </li>

              <li>
                <p>Manual: More browser-safe HTML-s. More updated
                content.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_222">Differences between the Preview 4 and Preview 3
            releases</h3>


            <ul>
              <li>
                <p>Bugfix: with multi-type variables, <code class="inline-code">+</code>
                operator overload for hash type had higher precedence than the
                precedence of some older overloads.</p>
              </li>

              <li>
                <p>The API documentation was missing from the distribution
                <code class="inline-code">tar.gz</code>.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_223">Differences between the Preview 3 and Preview 2
            releases</h3>


            <ul>
              <li>
                <p>XML processing: Many various bugfixes, especially with
                the declarative processing.</p>
              </li>

              <li>
                <p>XML processing: the <code class="inline-code">namespace_uri</code>
                built-in, the <code class="inline-code">xmlnsuri</code> header parameter,
                and the <code class="inline-code">TemplateNodeModel.getNodeNamespace</code>
                method were renamed to <code class="inline-code">node_namespace</code> and
                <code class="inline-code">getNodeNamespace</code> respectively.</p>
              </li>

              <li>
                <p>XML processing: Better documentation. Especially, note:
                <a href="xgui.html">XML处理指南</a></p>
              </li>

              <li>
                <p>A new header parameter, <code class="inline-code">strip_text</code>,
                that removes all top-level text from a template. See <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code>
                directive</a></p>
              </li>

              <li>
                <p>Support for a variable number of macro parameters. If
                the last parameter in a macro declaration ends with
                <code class="inline-code">...</code>, all extra parameters passed to the
                macro will be available via that parameter. For macros called
                with positional parameters, the parameter will be a sequence.
                For named parameters, the parameter will be a hash.</p>
              </li>

              <li>
                <p>For <code class="inline-code">BeansWrapper</code> generated models,
                you can now use the <code class="inline-code">${obj.method(args)}</code>
                syntax to invoke methods whose return type is
                <code class="inline-code">void</code>. <code class="inline-code">void</code> methods now
                return <code class="inline-code">TemplateModel.NOTHING</code> as their
                return value.</p>
              </li>
            </ul>
          

          
            



<h3 class="content-header header-section3" id="autoid_224">Differences between the Preview 2 and Preview 1
            releases</h3>


            <ul>
              <li>
                <p>The <code class="inline-code">freemarker.ext.dom.NodeModel</code> API
                changed slightly. The <code class="inline-code">setDocumentBuilder()</code>
                method was changed to
                <code class="inline-code">setDocumentBuilderFactory()</code> because the
                older scheme was not thread-safe. The
                <code class="inline-code">stripComments</code> and
                <code class="inline-code">stripPIs</code> methods are renamed to The
                <code class="inline-code">removeComments</code> and
                <code class="inline-code">removePIs</code>, and are fixed now. A new method,
                <code class="inline-code">simplify</code> has been added.</p>
              </li>

              <li>
                <p>The expressions <code class="inline-code">as</code>,
                <code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
                keywords in the template language and cannot be used as
                top-level variable names without square-bracket syntax (as
                <code class="inline-code">.vars[&quot;in&quot;]</code>). If, by some chance, you have
                top-level variables that use one of these names, you will have
                to rename them (or use the square-bracket syntax). Sorry for
                the inconvenience.</p>
              </li>

              <li>
                <p>The <code class="inline-code">?new</code> built-in, as it was
                implemented, was a security hole. Now, it only allows you to
                instantiate a java object that implements the
                <code class="inline-code">freemarker.template.TemplateModel</code>
                interface. If you want the functionality of the
                <code class="inline-code">?new</code> built-in as it existed in prior
                versions, make available an instance of the new
                <code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
                class to your template.</p>
              </li>

              <li>
                <p>The <code class="inline-code">&lt;#recurse&gt;</code> directive was
                broken. It did not work with a <code class="inline-code">using</code>
                clause. This is now fixed.</p>
              </li>
            </ul>
          
        <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_2_8.html"><span>Next</span></a></div></div></div></div>      </div>
    </div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="http://freemarker.org/index.html">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/nanlei/freemarker/tree/manual-zh-2.3-gae/src/manual">Chinese Manual on Github</a></li><li><a href="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://sourceforge.net/p/freemarker/bugs/new/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"><p><span class="generated-for-product">Generated for: Freemarker 2.3.23</span><span class="last-updated"> Last generated:
<time itemprop="dateModified" datetime="2015-09-18T14:38:51Z" title="Friday, September 18, 2015 2:38:51 PM GMT">2015-09-18 14:38:51 GMT</time></span></p> <p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2015
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://freemarker.org">The FreeMarker Project</a>. All rights reserved. </p>
</div></div></div></body>
</html>
